package org.emet.service.storage;

import java.math.BigDecimal;
import java.util.List;

import org.apache.log4j.Logger;
import org.emet.dao.storage.ItemDao;
import org.emet.dao.storage.SaleHistDao;
import org.emet.dao.storage.SaleItemDao;
import org.emet.entity.storage.Item;
import org.emet.entity.storage.SaleHist;
import org.emet.entity.storage.SaleItem;
import org.emet.jee.BusinessException;
import org.emet.jee.console.entity.security.User;
import org.emet.jee.console.services.security.SpringSecurityService;
import org.emet.jee.core.dao.Page;
import org.emet.service.dto.storage.SaleCriteria;
import org.hibernate.Transaction;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.flex.remoting.RemotingDestination;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional
@RemotingDestination
public class SaleMananger {
	private Logger logger = Logger.getLogger(SaleMananger.class);

	@Autowired
	private SpringSecurityService springSecurityService;
	@Autowired
	private SaleHistDao saleHistDao;
	@Autowired
	private ItemDao itemDao;
	@Autowired
	private SaleItemDao saleItemDao;

	public Page<SaleHist> searchPurchaseHistory(Page<SaleHist> page, SaleCriteria c) {
		return saleHistDao.search(page, c);
	}

	private boolean hasOperator(SaleHist sh) {
		return sh.getOperatorName() != null || sh.getOperatorSN() != null;
	}

	public void saveSell(SaleHist entity) {
		Transaction tx = saleHistDao.getSession().beginTransaction();
		try {
			saveOrUpdateSale(entity);
			tx.commit();
		} catch (Exception e) {
			tx.rollback();
			final String message = "保存出库信息是发生错误！";
			logger.error(message, e);
			throw new BusinessException(e);
		}
	}

	@Transactional
	public void saveOrUpdateSale(SaleHist entity) {
		final List<SaleItem> items = entity.getItems();
		// 减去库存数量和成本金额,修改加权价
		for (SaleItem entry : items) {
			entry.setDate(entity.getDate());
			entry.setSaleHist(entity);
			warehouseDeliver(entry);
		}

		//Edit
		if (entity.getId() != null) {
			SaleHist oldSaleHist = saleHistDao.get(entity.getId());
			List<SaleItem> oldItems = oldSaleHist.getItems();
			//remove all old ones;
			for (SaleItem saleItem : oldItems) {
				//put back the good items to ware hourse.
				importWareHouse(saleItem);
				saleItemDao.delete(saleItem);
			}
			oldSaleHist.setCustomer(entity.getCustomer());
			oldSaleHist.setDate(entity.getDate());
			List<SaleItem> newItems = entity.getItems();
			for (SaleItem saleItem : newItems) {
				saleItem.setSaleHist(oldSaleHist);
			}
			oldSaleHist.setItems(newItems);
		} else {
			if (!hasOperator(entity)) {
				User currentUser = springSecurityService.getUser();
				if (currentUser != null) {
					entity.setOperatorSN(currentUser.getStaffNumber());
					entity.setOperatorName(currentUser.getName());
				}
			}

			saleHistDao.save(entity);
		}

	}

	public void deleteSell(long id) {
		delSale(id);
	}

	@Transactional(propagation = Propagation.SUPPORTS)
	public void delSale(long id) {
		SaleHist history = saleHistDao.get(id);
		if (history == null)
			return;

		// 增加库存数量和成本金额
		List<SaleItem> items = history.getItems();
		for (SaleItem saleItem : items) {
			importWareHouse(saleItem);
		}

		try {
			saleHistDao.delete(id);
		} catch (Exception e) {
			final String message = "删除出库信息是发生错误！";
			logger.error(message, e);
			throw new BusinessException(e);
		}
	}

	//入库
	private void importWareHouse(SaleItem entry) {
		Item oldItem = itemDao.get(entry.getItem().getId());
		final int stockQuatity = oldItem.getStockQuatity() + entry.getItemCount();

		if (stockQuatity < 0) {
			oldItem.setStockQuatity(0);
		}

		oldItem.setStockQuatity(stockQuatity);

		/** 成本总额 */
		BigDecimal costAmount = oldItem.getTotalCost().add(entry.getAmount());
		if (costAmount.compareTo(new BigDecimal(0.00)) < 0) {
			/** 已经收回成本 */
			costAmount = new BigDecimal(0.00);
		}
		oldItem.setTotalCost(costAmount);

		if (oldItem.getStockQuatity() == 0) {
			oldItem.setWeightPrice(new BigDecimal(0.00));
		} else {
			BigDecimal weightPrice = ItemHelper.calculateWeight(oldItem.getTotalCost(), oldItem.getStockQuatity());
			oldItem.setWeightPrice(weightPrice);
		}
	}

	public java.sql.Date getDate() {
		return new java.sql.Date(new java.util.Date().getTime());
	}

	/**
	 * 减去该物品的库存数量和成本
	 * 
	 * @param entry
	 */
	public void warehouseDeliver(SaleItem entry) {
		Item oldItem = itemDao.get(entry.getItem().getId());
		final int stockQuatity = oldItem.getStockQuatity() - entry.getItemCount();

		if (stockQuatity < 0)
			throw new BusinessException(oldItem.getName() + "库存不足！ 库存为" + oldItem.getStockQuatity());

		oldItem.setStockQuatity(stockQuatity);

		/** 检测是否已经收回成本 */
		if (oldItem.getTotalCost().compareTo(new BigDecimal(0.00)) != 0) {
			/** 成本总额 */
			BigDecimal costAmount = oldItem.getTotalCost().subtract(entry.getAmount());
			if (costAmount.compareTo(new BigDecimal(0.00)) < 0) {
				/** 已经收回成本 */
				costAmount = new BigDecimal(0.00);
			}
			oldItem.setTotalCost(costAmount);
		}

		if (oldItem.getStockQuatity() == 0) {
			oldItem.setWeightPrice(new BigDecimal(0.00));
		} else {
			BigDecimal weightPrice = ItemHelper.calculateWeight(oldItem.getTotalCost(), oldItem.getStockQuatity());
			oldItem.setWeightPrice(weightPrice);
		}
	}
}
